package com.xdf.ecommerce.service.impl;

import com.alibaba.fastjson.JSON;
import com.xdf.ecommerce.constant.AuthorityConstant;
import com.xdf.ecommerce.constant.CommonConstant;
import com.xdf.ecommerce.dao.EcommerceUserMapper;
import com.xdf.ecommerce.entity.EcommerceUser;
import com.xdf.ecommerce.service.JWTService;
import com.xdf.ecommerce.utils.LocalDateTimeUtils;
import com.xdf.ecommerce.utils.RSAUtils;
import com.xdf.ecommerce.vo.LoginUserInfo;
import com.xdf.ecommerce.vo.UsernameAndPassword;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @author chanchaw
 * @create 2025-10-16 7:43
 */
@RequiredArgsConstructor
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class JWTServiceImpl implements JWTService {
    private final EcommerceUserMapper userMapper;
    @Override
    public String generateToken(String username, String passwrod) throws NoSuchAlgorithmException, IOException, InvalidKeySpecException {
        return generateToken(username,passwrod,AuthorityConstant.TOKEN_EXPIRE_MINUTE);
    }

    @Override
    public String generateToken(String username, String password, int expire) throws NoSuchAlgorithmException, IOException, InvalidKeySpecException {
        EcommerceUser user = userMapper.get8UsernameAndPassword(username, password);
        if(user == null) {
            log.info("没有找到用户：[{}]/[{}]",username,password);
            return null;
        }
        LoginUserInfo loginUserInfo = new LoginUserInfo();
        loginUserInfo.setId(user.getId());
        loginUserInfo.setUsername(user.getUsername());
        if(expire <= 0) expire = AuthorityConstant.TOKEN_EXPIRE_MINUTE;

        LocalDateTime localDateTime = LocalDateTime.now().plusSeconds(expire * 60);
        Date expiredDate = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());

        return Jwts.builder()
                // jwt payload 数据
                .claim(CommonConstant.JWT_USER_INFO_KEY, JSON.toJSONString(loginUserInfo))
                .setId(UUID.randomUUID().toString())
                .setExpiration(expiredDate)// 过期时间
                .signWith(getPrivateKey(), SignatureAlgorithm.RS256).compact();
    }

    /**
     * 注册新用户后立即创建 JWT token 并返回给用户
     * @param usernameAndPassword MD5加密后密码的密文
     * @return
     * @throws NoSuchAlgorithmException
     * @throws IOException
     * @throws InvalidKeySpecException
     */
    @Override
    public String registerAndGetToken(UsernameAndPassword usernameAndPassword) throws NoSuchAlgorithmException, IOException, InvalidKeySpecException {
        if(usernameAndPassword == null) throw new RuntimeException("没有传入用户密码数据，无法创建新用户！");

        List<EcommerceUser> userList = userMapper.get8Username(usernameAndPassword.getUsername());
        if(userList != null && userList.size() > 0) throw new RuntimeException("用户" + usernameAndPassword.getUsername() + "已存在，请更换用户名！");

        EcommerceUser user = new EcommerceUser();
        user.setUsername(usernameAndPassword.getUsername());
        user.setPassword(usernameAndPassword.getPassword());
        int i = userMapper.insertSelective(user);
        return generateToken(usernameAndPassword.getUsername(), usernameAndPassword.getPassword());
    }

    @Override
    public PrivateKey getPrivateKey() throws NoSuchAlgorithmException, IOException, InvalidKeySpecException {
        return RSAUtils.getPrivateKey(AuthorityConstant.RSA_PRIVATE_KEY);
    }
}
